import { RouteRecordRaw, _RouteRecordBase } from 'vue-router';
import { storeToRefs } from 'pinia';
import pinia from '/@/stores/index';
import { useUserInfo } from '/@/stores/userInfo';
import { useRequestOldRoutes } from '/@/stores/requestOldRoutes';
import { Session } from '/@/utils/storage';
import { NextLoading } from '/@/utils/loading';
import { dynamicRoutes, notFoundAndNoPower } from '/@/router/route';
import { formatTwoStageRoutes, formatFlatteningRoutes, router } from '/@/router/index';
import { useRoutesList } from '/@/stores/routesList';
import { useWebSite } from '../stores/websiteState';
import { useThemeConfig } from '/@/stores/themeConfig';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
import { httpReqeustApi } from '/@/api/linxyun/base/index';
import { backDynamicRoutes } from '/@/router/backroute';
import { ElMessage } from 'element-plus';

const httpReqeust = httpReqeustApi();

const layouModules: any = import.meta.glob('../layout/routerView/*.{vue,tsx}');
const viewsModules: any = import.meta.glob('../views/**/*.{vue,tsx}');

declare module 'vue-router' {
	interface _RouteRecordBase {
		code: string;
	}
}

// 后端控制路由

/**
 * 获取目录下的 .vue、.tsx 全部文件
 * @method import.meta.glob
 * @link 参考：https://cn.vitejs.dev/guide/features.html#json
 */
const dynamicViewsModules: Record<string, Function> = Object.assign({}, { ...layouModules }, { ...viewsModules });

/**
 * 后端控制路由：初始化方法，防止刷新时路由丢失
 * @method NextLoading 界面 loading 动画开始执行
 * @method useUserInfo().setUserInfos() 触发初始化用户信息 pinia
 * @method useRequestOldRoutes().setRequestOldRoutes() 存储接口原始路由（未处理component），根据需求选择使用
 * @method setAddRoute 添加动态路由
 * @method setFilterMenuAndCacheTagsViewRoutes 设置路由到 vuex routesList 中（已处理成多级嵌套路由）及缓存多级嵌套数组处理后的一维数组
 */
export async function initBackEndControlRoutes() {
	// 界面 loading 动画开始执行
	if (window.nextLoading === undefined) NextLoading.start();
	// 无 token 停止执行下一步
	if (!Session.get('token')) {
		NextLoading.done();
		return false;
	}
	// 触发初始化用户信息 pinia
	await useUserInfo().setUserInfos(null);
	await useWebSite(pinia).getWebSite();
	// 获取路由菜单数据
	const res = await getBackEndControlRoutes();
	console.log('getBackEndControlRoutes', { ...res[0].children });

	// 存储接口原始路由（未处理component），根据需求选择使用
	// useRequestOldRoutes().setRequestOldRoutes(JSON.parse(JSON.stringify(res.data)));
	useRequestOldRoutes().setRequestOldRoutes(JSON.parse(JSON.stringify(res)));
	// 处理路由（component），替换 dynamicRoutes（/@/router/route）第一个顶级 children 的路由
	dynamicRoutes[0].children = await backEndComponent((res as Array<any>)[0].children);
	dynamicRoutes[0].children?.push({
		path: '/menuPage',
		name: '菜单页面',
		code: 'F20020005',
		component: () => import('/@/views/linxyun/menuPage/menuPage.vue'),
		meta: {
			title: '菜单页面',
			isLink: '',
			isHide: true,
			isKeepAlive: true,
			isAffix: true,
			isIframe: false,
			roles: ['admin', 'common'],
			icon: 'iconfont icon-shouye',
		},
	});
	// 添加动态路由
	await setAddRoute();
	// 设置路由到 vuex routesList 中（已处理成多级嵌套路由）及缓存多级嵌套数组处理后的一维数组
	await setFilterMenuAndCacheTagsViewRoutes();
	NextLoading.done();
}

/**
 * 设置路由到 vuex routesList 中（已处理成多级嵌套路由）及缓存多级嵌套数组处理后的一维数组
 * @description 用于左侧菜单、横向菜单的显示
 * @description 用于 tagsView、菜单搜索中：未过滤隐藏的(isHide)
 */
export function setFilterMenuAndCacheTagsViewRoutes() {
	const storesRoutesList = useRoutesList(pinia);
	storesRoutesList.setRoutesList(dynamicRoutes[0].children as any);
	setCacheTagsViewRoutes();
}

/**
 * 缓存多级嵌套数组处理后的一维数组
 * @description 用于 tagsView、菜单搜索中：未过滤隐藏的(isHide)
 */
export function setCacheTagsViewRoutes() {
	const storesTagsView = useTagsViewRoutes(pinia);
	storesTagsView.setTagsViewRoutes(formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes))[0].children);
}

/**
 * 处理路由格式及添加捕获所有路由或 404 Not found 路由
 * @description 替换 dynamicRoutes（/@/router/route）第一个顶级 children 的路由
 * @returns 返回替换后的路由数组
 */
export function setFilterRouteEnd() {
	let filterRouteEnd: any = formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes));
	filterRouteEnd[0].children = [...filterRouteEnd[0].children, ...notFoundAndNoPower];
	return filterRouteEnd;
}

/**
 * 添加动态路由
 * @method router.addRoute
 * @description 此处循环为 dynamicRoutes（/@/router/route）第一个顶级 children 的路由一维数组，非多级嵌套
 * @link 参考：https://next.router.vuejs.org/zh/api/#addroute
 */
export async function setAddRoute() {
	await setFilterRouteEnd().forEach((route: RouteRecordRaw) => {
		router.addRoute(route);
	});
}

/**
 * 请求后端路由菜单接口
 * @description isRequestRoutes 为 true，则开启后端控制路由
 * @returns 返回后端路由菜单数据
 */
export async function getBackEndControlRoutes() {
	// 模拟 admin 与 test
	// const auth = userInfos.value.UserRoles[0];
	const res = await httpReqeust.SyncPost('getUserMenu', {}, { SubSysID: BASE_API.SubSysID });
	const menus = genRouteFromFunc(res);
	return menus;
}

function filterServerFunc(frontFuncs: Array<any>, serverFuncs: Array<any>) {
	console.log('frontFuncsfrontFuncs', frontFuncs, serverFuncs);

	return frontFuncs.filter((frontFunc) => {
		let filterResult = false;
		let equaFunc: any = null;
		serverFuncs.forEach((serverFunc) => {
			if (frontFunc.code === serverFunc.FuncCode) {
				filterResult = true;
				equaFunc = serverFunc;
				frontFunc.meta.icon = equaFunc.Icon;
			}
		});
		console.log('equaFunc', equaFunc, frontFunc);
		// 父级找不到相同的，子级全部删除
		if (filterResult && frontFunc.Child && frontFunc.Child instanceof Array && frontFunc.Child.length > 0) {
			// 相同的子级里面匹配
			if (equaFunc && equaFunc.Child && equaFunc.Child instanceof Array && equaFunc.Child.length > 0) {
				filterServerFunc(frontFunc.Child, equaFunc.Child);
			} else {
				filterServerFunc(frontFunc.Child, []);
			}
		}
		return filterResult;
	});
}

function createSyncRoute(frontRoutes: any, serverFuncs: Array<any>) {
	let isFound = false;
	for (let i = 0; i < serverFuncs.length; i++) {
		// frontRoutes.forEach((frontRoute) => {
		isFound = false;
		const serverFunc = serverFuncs[i];
		for (let j = 0; j < frontRoutes.length; j++) {
			const frontRoute = frontRoutes[j];
			isFound = false;
			// serverFuncs.forEach((serverFunc) => {
			// 匹配上了当前级，还需要匹配子级
			if (frontRoute.code === serverFunc.code) {
				isFound = true;
				if (!frontRoute.component || frontRoute.component.length <= 0) {
					// 当前端的component为空时，说明只是一个占位，需要用后端的替换
					// 占位符不管理子集，全部替换
					frontRoutes[j] = serverFunc;
				} else {
					// 比对子集,否则以前端的配置为准，再比对子集
					if (serverFunc.children && serverFunc.children instanceof Array && serverFunc.children.length > 0) {
						if (frontRoute.children && frontRoute.children instanceof Array && frontRoute.children.length > 0) {
							createSyncRoute(frontRoute.children, serverFunc.children);
						}
					}
				}
				break;
			}
		}
		if (!isFound) {
			frontRoutes.push(serverFunc);
		}
	}
}

function changeFuncToRoute(serverRoutes: Array<any>, serverFuncs: Array<any>) {
	for (let i = 0; i < serverFuncs.length; i++) {
		const func = serverFuncs[i];
		func.Icon = func.Icon || '';
		if (func.ComponentPath === undefined || func.ComponentPath === null || func.ComponentPath === '') {
			console.error('[Error][Route]ComponentPath is empty!', func.FuncName, func.ComponentPath);
			// func.ComponentPath = ''
		}
		let isKeepAlive = true;
		if (func.IsCache === undefined || func.IsCache === null || func.IsCache === '' || func.IsCache === '0') {
			isKeepAlive = false;
		}

		let isAffix = true;
		if (func.IsAffix === undefined || func.IsAffix === null || func.IsAffix === '' || func.IsAffix === '0') {
			isAffix = false;
		}

		// ReqType [1:isLink, 2:isIframe, 0或其它：普通路由]
		let isIframe = false;
		let isLink = false;
		if (func.ReqType === '1') {
			isLink = true;
		}
		if (func.ReqType === '2') {
			isIframe = true;
		}

		let icon = 'iconfont icon-caidan';
		if (func.Icon) {
			icon = func.Icon;
		}

		const hidden = func.FuncType === '9' || func.FuncType === '2'; // 9 隐藏
		const routeItem = {
			path: func.FuncUrl,
			name: func.FuncName,
			code: func.FuncCode,
			// component: (resolve) => require([`@/views${func.ComponentPath}`], resolve),
			component: func.ComponentPath,
			meta: {
				title: func.FuncName,
				isLink: isLink,
				isHide: hidden,
				isKeepAlive: isKeepAlive,
				isAffix: isAffix,
				isIframe: isIframe,
				auth: ['admin'],
				icon: icon,
			},
		} as any;
		if (func.Child && func.Child instanceof Array && func.Child.length > 0) {
			routeItem.children = [];
			serverRoutes.push(routeItem);
			changeFuncToRoute(routeItem.children, func.Child);
		} else {
			serverRoutes.push(routeItem);
		}
	}
}

function genRouteFromFunc(res: any) {
	const funcs = res.data;
	console.log('[Debug][RouteData]: ', funcs);
	// let funcsData = []
	// 过滤掉服务端没有的路由
	const accessedRoutes = filterServerFunc(backDynamicRoutes[0].children, funcs.Child) as any;
	// const accessedRoutes = backDynamicRoutes[0].children;
	console.log('accessedRoutes', { ...accessedRoutes });

	// 将服务端返回的功能树挂载到动态路由对像中
	const serverRoutes = [] as Array<any>;
	if (funcs && funcs.Child) {
		changeFuncToRoute(serverRoutes, funcs.Child);
		createSyncRoute(accessedRoutes, serverRoutes);
		// 还需要对Home和根做特殊处理
		// if (BASE_API.NEED_HOME) {
		// 	const homeRoute = {
		// 		path: '/home',
		// 		name: 'home',
		// 		component: () => import('/@/views/home/index.vue'),
		// 		meta: {
		// 			title: 'message.router.home',
		// 			isLink: '',
		// 			isHide: false,
		// 			isKeepAlive: true,
		// 			isAffix: true,
		// 			isIframe: false,
		// 			roles: ['admin', 'common'],
		// 			icon: 'iconfont icon-shouye',
		// 		},
		// 	};
		// 	console.log('homeRoute', homeRoute);
		// 	accessedRoutes.children.unshift(homeRoute);
		// }

		if (accessedRoutes && accessedRoutes.length > 0) {
			backDynamicRoutes[0].children = accessedRoutes;
		}
	} else {
		console.error('getMenus return null');
		ElMessage({
			message: '没有获取到用户的路由信息!',
			type: 'error',
			duration: BASE_API.MSG_SHOW_TIME,
		});
	}
	return backDynamicRoutes;
}

/**
 * 重新请求后端路由菜单接口
 * @description 用于菜单管理界面刷新菜单（未进行测试）
 * @description 路径：/src/views/system/menu/component/addMenu.vue
 */
export function setBackEndControlRefreshRoutes() {
	getBackEndControlRoutes();
}

/**
 * 后端路由 component 转换
 * @param routes 后端返回的路由表数组
 * @returns 返回处理成函数后的 component
 */
export function backEndComponent(routes: any) {
	if (!routes) return;

	return routes.map((item: any) => {
		if (item.path === '/UserManage') {
			console.log(item, dynamicViewsModules);
			debugger;
		}
		if (item.component) item.component = dynamicImport(dynamicViewsModules, ('/' + item.component) as string);
		item.children && backEndComponent(item.children);
		return item;
	});
}

/**
 * 后端路由 component 转换函数
 * @param dynamicViewsModules 获取目录下的 .vue、.tsx 全部文件
 * @param component 当前要处理项 component
 * @returns 返回处理成函数后的 component
 */
export function dynamicImport(dynamicViewsModules: Record<string, Function>, component: string) {
	const keys = Object.keys(dynamicViewsModules);
	const matchKeys = keys.filter((key) => {
		const k = key.replace(/..\/views|../, '');
		return k.startsWith(`${component}`) || k.startsWith(`/${component}`);
	});
	if (matchKeys?.length === 1) {
		const matchKey = matchKeys[0];
		return dynamicViewsModules[matchKey];
	}
	if (matchKeys?.length > 1) {
		return false;
	}
}
